/**
 * 
 */
package org.vsg.stock.basic;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationFactory;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vsg.stock.core.domain.StockTick;

/**
 * @author vison
 *
 */
public class StockHelper {
	
	public final static short OVER_SELL_SHOWN_PRICE = 7;
	
	public final static short INVISIBLE_AT_SELL_PRICE = 6;
	
	public final static short VISIBLE_AT_SELL_PRICE = 5;
	
	public final static short AT_TRADING_PRICE = 4;
	
	public final static short VISIBLE_AT_BUY_PRICE = 3;
	
	public final static short INVISIBLE_AT_BUY_PRICE =2;

	public final static short UNDER_BUY_SHOWN_PRICE = 1;	
	
	private static StockHelper helper;
	
	private static List<String> notTradeDays = null;
	
	private static SimpleDateFormat sdf = new SimpleDateFormat("MM-dd");

	private static final Logger logger = LoggerFactory.getLogger(StockHelper.class);
	
	
	private StockHelper() throws Exception{
		
		String configPath = System.getProperty("config.path");
		
		if (configPath == null) {
			String message = "Do not set the -Dconfig.path argument!";
			logger.info(message);
			throw new Exception(message);
		} else {
			
			String sysConfiguration = configPath+"//system.xml";
			ConfigurationFactory factory = new ConfigurationFactory(sysConfiguration);
			Configuration config = factory.getConfiguration();

			InputStream is = null;
			List<String> lines = null;
			try {
				
				if (config.getString("stock.tradedays") == null) {
					is = ClassLoader.getSystemResourceAsStream("nottradedays.txt");
					logger.info( "property 'stock.tradedays' is null ! " );
				} else {
					is = new FileInputStream( config.getString("stock.tradedays") );
				}
				if (is != null) {
					lines = IOUtils.readLines(is);
				} else {
					lines = new Vector();
				}

			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				if (is != null) {
					try {
						is.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} finally {
						is = null;
					}
				}
			}
			notTradeDays = lines;			
		}

	}
	

	private void init() {
		
	}
	
	
	public static StockHelper getInstance(){
		try {
			helper = new StockHelper();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		helper.init();
		
		return helper;
	}
	
	public  boolean isTradingDate(Date date) {
		Date tmpDate = null;
		Calendar tmpCale = Calendar.getInstance();
		tmpCale.setTime(date);		
	
		return isTradingDate(tmpCale);
	}

	
	public boolean isTradingDate(Calendar tmpCale) {
		
		if (tmpCale.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY 
				|| tmpCale.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ) {
			return false;
		}
		
		String dateStr = sdf.format( tmpCale.getTime() );
		if (notTradeDays.contains( dateStr )) {
			return false;
		}

		return true;
	}	

	public short getCurrentPricePosition(double currentPrice ,StockTick stockTick) {
		
		double sell5 = stockTick.getConsignedSell5Price();
		double sell4 = stockTick.getConsignedSell4Price();
		double sell3 = stockTick.getConsignedSell3Price();
		double sell2 = stockTick.getConsignedSell2Price();
		double sell1 = stockTick.getConsignedSell1Price();
		
		double buy1 = stockTick.getConsignedBuy1Price();
		double buy2 = stockTick.getConsignedBuy2Price();
		double buy3 = stockTick.getConsignedBuy3Price();
		double buy4 = stockTick.getConsignedBuy4Price();
		double buy5 = stockTick.getConsignedBuy5Price();
		
		
		if (currentPrice > sell5) {
			return OVER_SELL_SHOWN_PRICE;
		}
		else if (currentPrice < buy5) {
			return UNDER_BUY_SHOWN_PRICE;
		}
		else if ( currentPrice < sell1 && currentPrice > buy1) {
			return AT_TRADING_PRICE;
		}
		else if ( currentPrice <= sell5 && currentPrice >= sell1) {
			if (currentPrice == sell1 
				|| currentPrice == sell2
				|| currentPrice == sell3
				|| currentPrice == sell4
				|| currentPrice == sell5
			) {
				return VISIBLE_AT_SELL_PRICE;
			} else {
				return INVISIBLE_AT_SELL_PRICE;
			}
		}
		else if ( currentPrice <= buy1 && currentPrice >= buy5) {
			if (currentPrice == buy1 
				|| currentPrice == buy2
				|| currentPrice == buy3
				|| currentPrice == buy4
				|| currentPrice == buy5
			) {
				return VISIBLE_AT_BUY_PRICE;
			} else {
				return INVISIBLE_AT_BUY_PRICE;
			}
		}
		
		return 0;
	}

	
}
